package com.rock.sys.intercept;

import java.util.Date;
import java.util.List;

import com.eova.aop.AopContext;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;
import com.rock.sys.global.RockMetaIntercept;
import com.rock.sys.model.TSAppRole;
import com.rock.sys.model.TSPage;
import com.rock.sys.model.TSPageComp;
import com.rock.sys.util.PinYin;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;

public class AppAdminIntercept extends RockMetaIntercept {

    /**
     * 新增前置任务(事务内) ，添加默认执行方法（新增字段处理）
     * <pre>
     * ac.record 当前操作数据
     * -------------
     * 用法：自动赋值
     * ac.record.set("reg_time", new Date());
     * ac.record.set("user_id", ac.user.get("id"));
     *
     * 用法：唯一值判定
     * int count = Db.queryInt("select count(*) from users where name = ?", ac.record.getStr("name"));
     * if (count > 0) {
     *     return Easy.error("名字不能重复");
     * }
     * </pre>
     */
	@Override
    public String addBefore(AopContext ac) throws Exception {
		String r = super.addBefore(ac);
		if(!StrUtil.isBlankIfStr(r)) {
			return r;
		}

    	//设置编码，APP名称首字母_日期
    	String name = ac.record.getStr("app_name");
    	String codePre = PinYin.getFirstLeter(name) + "_";
    	
		//设置编码为在线表单固定前缀
    	String date = DateUtil.format(new Date(), "HHmmss");
    	String code = codePre + date;
    	
    	//检查APP编码是否已存在
        int count = Db.queryInt("select count(*) from t_s_app where app_code = ?", code);
        if(count > 0) {
        	//重置编码
        	code = codePre + Long.toString(System.currentTimeMillis()/1000L);
        }
        ac.record.set("app_code", code);
    	
        return null;
    }
    
	/**
     * 新增后置任务(事务内)
     * <pre>
     * ac.record 当前操作数据
     * -------------
     * 用法：级联新增，需在同事务内完成
     * int id = ac.record.getInt("id");// 获取当前对象主键值，进行级联新增
     * </pre>
     */
	@Override
    public String addAfter(AopContext ac) throws Exception {
		String r = super.addAfter(ac);
		if(!StrUtil.isBlankIfStr(r)) {
			return r;
		}
		
		//获取app类型
		String typeId = ac.record.getStr("type_id");

		if(StrUtil.isBlank(typeId)) {
			return "必须选择一个APP类型";
		}
		
		String templateAppId = Db.queryStr("select t.template_app_id from t_s_app_type t where t.id=?",typeId);

		if(StrUtil.isBlank(templateAppId)) {
			return "失败，未找到所选APP类型所对应的模板APP";
		}
		
		//复制模板APP的所有页面和组件
		copyAppPageAndComp(templateAppId,ac.record.getStr("id"),ac.record.getStr("tenant_id"));
		
		//复制模板APP的所有角色，并自动相对随机的分配权限
		copyAppRoleAndComp(templateAppId,ac.record.getStr("id"),ac.record.getStr("tenant_id"));
		
        return null;
    }

	/**
     * 删除后置任务(事务内)
     * <pre>
     * ac.record    当前删除对象数据
     * -------------
     * 用法：级联删除，父对象删除时级联删除子对象，同一个事务内
     * </pre>
     */
	@Override
    public String deleteAfter(AopContext ac) throws Exception {
		String r = super.deleteAfter(ac);
		if(!StrUtil.isBlankIfStr(r)) {
			return r;
		}

		//同步删除APP相关数据
		String id = ac.record.getStr("id");
		//删除页面组件
		Db.delete("delete from t_s_page_comp where app_id=?", id);
		//删除页面
		Db.delete("delete from t_s_page where app_id=?", id);
		//删除角色
		Db.delete("delete from t_s_app_role where app_id=?", id);
		
		
		return null;
	}
	

	/**
	 * 复制APP的页面及组件
	 * @param srcAppId
	 * @param appId
	 * @param tenantId
	 */
	public static void copyAppPageAndComp(String srcAppId, String appId, String tenantId) {

		//复制新的数据
		List<TSPage> lstP = TSPage.dao.find("select * from t_s_page where app_id=?",srcAppId);
		
		for(TSPage item : lstP) {
			
			//原ID
			long oid = item.getId();
			//先查询原页面下的所有组件
			List<TSPageComp> artLstOld = TSPageComp.dao.find("select * from t_s_page_comp where page_id=?",item.getId());
			
			//复制页面
			TSPage newItem = item.remove("id").remove("create_user").remove("update_user").remove("update_time");
			newItem.setAppId(Integer.parseInt(appId));
			newItem.setTenantId(Integer.parseInt(tenantId));
			newItem.setCreateTime(new Date());
			newItem.save();
			
			//复制新页面下的组件
			copyCompsByPage(artLstOld,newItem);
		}
	}


	/**
	 * 根据页面复制组件
	 * @param compLst
	 * @param newPage
	 */
	public static void copyCompsByPage(List<TSPageComp> compLst, TSPage newPage) {
		for(TSPageComp item : compLst) {
			//复制组件
			TSPageComp newItem = item.remove("id").remove("create_user").remove("update_user").remove("update_time");
			newItem.setAppId(newPage.getAppId());
			newItem.setTenantId(newPage.getTenantId());
			newItem.setCreateTime(new Date());
			//设置归属页面
			newItem.setPageId(newPage.getId());
			newItem.save();
		}
	}
	

    private void copyAppRoleAndComp(String srcAppId, String appId, String tenantId) {

		//复制新的数据
		List<TSAppRole> lsR = TSAppRole.dao.find("select * from t_s_app_role where app_id=?",srcAppId);
		
		//新的app下的所有页面
		List<TSPage> lstP = TSPage.dao.find("select * from t_s_page where app_id=? order by sort_no",appId);
		
		for(int i=0;i<lsR.size();i++) {
			
			TSAppRole item = lsR.get(i);
			//复制角色
			TSAppRole newRole = item.remove("id").remove("create_user").remove("update_user").remove("update_time");
			newRole.setAppId(Integer.parseInt(appId));
			newRole.setTenantId(Integer.parseInt(tenantId));
			newRole.setCreateTime(new Date());
			newRole.save();
			
			if(i==0) {
				//第一个永远是默认角色，给所有页面组件权限
				for(int p=0;p<lstP.size();p++) {
					//先查询页面下的所有组件
					List<TSPageComp> artLstOld = TSPageComp.dao.find("select * from t_s_page_comp where page_id=?",lstP.get(p).getId());
					for(TSPageComp comp : artLstOld) {
						Record roleComp = new Record();
						roleComp.set("app_id", appId);
						roleComp.set("rid", newRole.getId());
						roleComp.set("page_id", comp.getPageId());
						roleComp.set("comp_id", comp.getId());
						Db.save("t_s_app_role_comps", roleComp);
					}
					
				}
			} else {
				//非默认角色，第一个角色给第一个页面+最后一个页面，第二个角色给第二个页面+最后一个页面，依次类推
				for(int p=0;p<lstP.size();p++) {
					if(p==i-1 || p==lstP.size()-1) {
						//先查询页面下的所有组件
						List<TSPageComp> artLstOld = TSPageComp.dao.find("select * from t_s_page_comp where page_id=?",lstP.get(p).getId());
						for(TSPageComp comp : artLstOld) {
							Record roleComp = new Record();
							roleComp.set("app_id", appId);
							roleComp.set("rid", newRole.getId());
							roleComp.set("page_id", comp.getPageId());
							roleComp.set("comp_id", comp.getId());
							Db.save("t_s_app_role_comps", roleComp);
						}
					}
					
				}
				
			}
		}
	}
}
